d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;
function eventInWidget(display, e) { for (var n = e_target(e); n != display.wrapper; n = n.parentNode) { if (!n || n.ignoreEvents || n.parentNode == display.sizer && n != display.mover) return true;
function posFromMouse(cm, e, liberal, forRect) { var display = cm.display;
var target = e_target(e);
if (target == display.scrollbarH || target == display.scrollbarV ||
target == display.scrollbarFiller || target == display.gutterFiller) return null;
var x, y, space = display.lineSpace.getBoundingClientRect();
x = e.clientX - space.left; y = e.clientY - space.top;
if (!x && !y && e.touches && e.touches.length===1) { x = e.touches[0].clientX - space.left;
y = e.touches[0].clientY - space.top;
} catch (e) { return null; } var coords = coordsChar(cm, x, y), line;
if (forRect && coords.xRel == 1 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) { var colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length;
coords = Pos(coords.line, Math.max(0, Math.round((x - paddingH(cm.display).left) / charWidth(cm.display)) - colDiff));
function onMouseDown(e) { if (signalDOMEvent(this, e)) return;
var cm = this, display = cm.display;
display.shift = e.shiftKey;
if (eventInWidget(display, e)) { display.scroller.draggable = false;
setTimeout(function(){display.scroller.draggable = true;}, 100); if (clickInGutter(cm, e)) return;
var start = posFromMouse(cm, e);
leftButtonDown(cm, e, start);
else if (e_target(e) == display.scroller)
if (webkit) cm.state.lastMiddleDown = +new Date;
if (start) extendSelection(cm.doc, start);
setTimeout(bind(focusInput, cm), 20);
if (captureRightClick) onContextMenu(cm, e);